<?php

namespace app\api\controller;

use app\common\controller\Api;
use app\api\controller\AesUtil;
use think\Config;
use addons\workorder\library\General;
use app\common\controller\Frontend;
use addons\workorder\model\Orders;
use app\common\model\User;
use Exception;
use WechatPay\GuzzleMiddleware\Util\MediaUtil;
use GuzzleHttp\Exception\RequestException;
use WechatPay\GuzzleMiddleware\WechatPayMiddleware;
use WechatPay\GuzzleMiddleware\Util\PemUtil;

/**
 * 会员接口
 */
class Complaincommon extends Frontend
{
    protected $noNeedLogin = ['complainCallBack','testInfo','uploadImg','replyComplain','closeComplain','uploadImg4','getCertificateLKC','getComplainDetail','getComplainImage','getHistorys','createComplainUrl','updateComplainUrl'];
    protected $noNeedRight = '*';
    protected $General = null;

    public $wechatpayCertificate = null;
    public $merchantId = null; // 商户号
    public $merchantSerialNumber = null; // 商户API证书序列号
    public $merchantPrivateKey = null; // 商户私钥
    public $client = null;

    public function __construct($out_trade_no = null,$order_id = null,$mch_id = null)
    {
        parent::__construct();

        if (!Config::get('fastadmin.usercenter')) {
            $this->error(__('User center already closed'));
        }
        if($out_trade_no || $order_id || $mch_id){
            
            if($out_trade_no){
                $complainted_mchid_data = db('workorder_orders')->where('out_trade_no',$out_trade_no)->find();
                $this->merchantId = $complainted_mchid_data['complainted_mchid'];
            }
            if($order_id){
                $complainted_mchid_data = db('workorder_orders')->where('id',$order_id)->find();
                $this->merchantId = $complainted_mchid_data['complainted_mchid'];
            }
            if($mch_id){
                $this->merchantId = $mch_id;
            }

            $serial_number = db('certificate_differ')->where('MCHID',$this->merchantId)->find();
            $this->merchantSerialNumber = $serial_number['serial_number'];

            $this->wechatpayCertificate = file_get_contents('./wechatpayCertificate/'.$this->merchantId.'/wechatpayCertificate.pem');
            $this->merchantPrivateKey = PemUtil::loadPrivateKey('./certificate/'.$this->merchantId.'/cert/apiclient_key.pem');
            // 构造一个WechatPayMiddleware
            $wechatpayMiddleware = WechatPayMiddleware::builder()
                ->withMerchant($this->merchantId, $this->merchantSerialNumber, $this->merchantPrivateKey) // 传入商户相关配置
                ->withWechatPay([ $this->wechatpayCertificate ]) // 可传入多个微信支付平台证书，参数类型为array
                ->build();

            // 将WechatPayMiddleware添加到Guzzle的HandlerStack中
            $stack = \GuzzleHttp\HandlerStack::create();
            $stack->push($wechatpayMiddleware, 'wechatpay');

            // 创建Guzzle HTTP Client时，将HandlerStack传入
            $this->client = new \GuzzleHttp\Client(['handler' => $stack]);
        }
        
        
    }

    public function index()
    {
        $list = db('complain')->order('id desc')->select();
        $this->success('成功',$list);
    }

    // 投诉的回调地址
    /* public function complainCallBack(){
        $xml = file_get_contents('php://input');
        $sessionKey = "aa6661b2b1700feba54f10259b3b82cc";
        file_put_contents('./1.txt', json_encode($xml).PHP_EOL,FILE_APPEND);
        $this->decrypt($xml,$sessionKey);
        return 200;
        
    } */

    public function replyComplain($complaint_id,$complainted_mchid,$response_content = null,$response_images = null){
        try {
                
            $url = "https://api.mch.weixin.qq.com/v3/merchant-service/complaints-v2/{$complaint_id}/response";
            $data = [
                "complainted_mchid" =>$complainted_mchid
            ];
            $data['response_content'] = $response_content??'图片';
            if($response_images){
                $data['response_images']  = explode(',', trim($response_images, ','));
            }
           
            //print_r($data);exit;
            $sign                        = $this -> getSign_fen($url, 'POST',json_encode($data));//获取签名
            $sign                        = 'WECHATPAY2-SHA256-RSA2048 '.$sign; //认证类型  拼接 签名
            $res = http_post_json_complain($url,json_encode($data),  $sign);// http_post_json($url, $data, $sign); //请求接口
            if($res[0]==204){
                return true;
            }

        } catch (RequestException $e) {
            // 进行错误处理
            echo $e->getMessage()."\n";
            if ($e->hasResponse()) {
                echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
            }
            return;
        }
    }

    public function arrayToJson($array) {
        $jsonObject = '{';
        foreach ($array as $key => $value) {
            if (is_array($value)) {
                $jsonObject .= '"' . $key . '": ' . $this->arrayToJson($value) . ',';
            } else {
                $jsonObject .= '"' . $key . '": "' . $value . '",';
            }
        }
        $jsonObject = rtrim($jsonObject, ',');
        $jsonObject .= '}';
        return $jsonObject;
    }
     

    //关闭投诉
    public function closeComplain($complaint_id,$complainted_mchid){
        try {

            $url = "https://api.mch.weixin.qq.com/v3/merchant-service/complaints-v2/{$complaint_id}/complete";
            $data = [
                "complainted_mchid" =>$complainted_mchid
            ];
            $sign                        = $this -> getSign_fen($url, 'POST',json_encode($data));//获取签名
            $sign                        = 'WECHATPAY2-SHA256-RSA2048 '.$sign; //认证类型  拼接 签名
            
            http_post_json_complain($url,json_encode($data),  $sign);// http_post_json($url, $data, $sign); //请求接口
        }catch (RequestException $e) {
            // 进行错误处理
            echo $e->getMessage()."\n";
            if ($e->hasResponse()) {
                echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
            }
            return;
        }
    }

    //获取投诉详情
    public function getComplainDetail($complaint_id){

        // 接下来，正常使用Guzzle发起API请求，WechatPayMiddleware会自动地处理签名和验签
        try {
            $resp = $this->client->request('GET', 'https://api.mch.weixin.qq.com/v3/merchant-service/complaints-v2/'.$complaint_id, [ // 注意替换为实际URL
                'headers' => [ 'Accept' => 'application/json' ]
            ]);
            return $resp->getBody();
            echo $resp->getStatusCode().' '.$resp->getReasonPhrase()."\n";
            echo $resp->getBody()."\n";

            
        } catch (RequestException $e) {
            // 进行错误处理
            echo $e->getMessage()."\n";
            if ($e->hasResponse()) {
                echo $e->getResponse()->getStatusCode().' '.$e->getResponse()->getReasonPhrase()."\n";
                echo $e->getResponse()->getBody();
            }
            return;
        }

    }

    //获取图片
    public function getComplainImage($media_url){
        try {
            $resp = $this->client->request('GET', $media_url, [ // 注意替换为实际URL
                'headers' => [ 'Accept' => 'application/json' ]
            ]);
            echo $resp->getStatusCode().' '.$resp->getReasonPhrase()."\n";
            echo $resp->getBody()."\n";
            
        } catch (RequestException $e) {            
            if ($e->hasResponse()) {
                $url = 'https://api.mch.weixin.qq.com/v3/merchant-service/images/';
                $media_id = preg_replace('#^'.$url.'#','',$media_url);

                $media_res = db('workorder_records')->where('media_id',$media_id)->find();
                if(!$media_res){
                    $dir = "./uploads/";
                    $date_dir = date('Ymd',time()).'/';
                    $filename = md5(uniqid()).'.png';
                    $full_path = $dir.$date_dir.$filename;
                    $mode = 0777;//最高权限
                    if (is_dir($dir.$date_dir) == false) {//如果路径不存在，则创建
                        @mkdir($dir.$date_dir, $mode,true);
                    }
                    file_put_contents($full_path,$e->getResponse()->getBody());
                    print_r(['https://complain.lkcsz.com/uploads/'.$date_dir.$filename,$media_id]);
                    return json_encode(['full_path'=>'https://complain.lkcsz.com/uploads/'.$date_dir.$filename,'media_id'=>$media_id]);
                }                 
            }
            return;
        }

    }

    public function testInfo(){
        $xml = '{"id":"31911e55-c888-57f7-a0d2-97c5aa97f502","create_time":"2025-03-31T17:18:50+08:00","resource_type":"encrypt-resource","event_type":"COMPLAINT.STATE_CHANGE","summary":"u6295u8bc9u72b6u6001u53d8u66f4","resource":{"original_type":"complaint","algorithm":"AEAD_AES_256_GCM","ciphertext":"eWa0HO/bsDKgkFJFJ7LdMUGcQfqpzXtyZ/9+B3AoJ7NJD3bVfG/WZzRw2RuXIk+0h/Y3zobgUCpfxIuGYCGXA6aZq8YTU9/4MoOKL8T8qMrYe0GZKbs7WYvd5yzvpiKAeW6JC98Ok7hGuDDB1vKGoFNGQMd0g5MCfqY1krgreh58+9VaU4hiP/JIRybiNzCBoNmx94VBqWG1E2kVJXzO7ZY/+EoqWcX/jHkHg2SCqiSOfGwntFAprm/1p23BAR/ljtOzSSPnlEwR36tw3UEMDu3/I32724p1ZlkjQB8WS1AvVzlVsSd2PaQ29vgKXy+AZBga8wonWjo3bW8tRn1p91l/YRVYUQD+r9OAfebTBA7LSFssM9uUx1dMPiNYIBhg4O26hPvciT3sq2haomE2YnJjTs/dZKMoVXxrT65o0T39Vg/RS8UQUhcwNp0fceycci2/dnmKorQExZY=","associated_data":"complaint","nonce":"KMQwthb1FWfv"}}';
        $this->decrypt($xml,'aa6661b2b1700feba54f10259b3b82cc');
        exit;
        $data = json_decode($xml,true);
        $ciphertext = $data['resource']['ciphertext'];
        $nonce = $data['resource']['nonce'];
        $associated_data = $data['resource']['associated_data'];
        $aesutil = new AesUtil('aa6661b2b1700feba54f10259b3b82cc');
        $res = json_decode($aesutil->decryptToString($associated_data, $nonce, $ciphertext),true);

        $postData['out_trade_no'] = $out_trade_no = $res['out_trade_no'];
        $post_url = 'https://testlkc.lkcsz.com/treasure/index/getMchidByOrderNo?orderNo='.$out_trade_no;
        $mch_id = curlPost($post_url,$postData);

        print_r([$res,$mch_id,$mch_id->data->mchid]);
    }

    public function getHistorys($complaint_id){
        try {
            $resp = $this->client->request('GET', 'https://api.mch.weixin.qq.com/v3/merchant-service/complaints-v2/'.$complaint_id.'/negotiation-historys', [ // 注意替换为实际URL
                'headers' => [ 'Accept' => 'application/json' ]
            ]);
            /* 
            
            echo $resp->getStatusCode().' '.$resp->getReasonPhrase()."\n"; */
            return $resp->getBody()."\n";

            
        } catch (RequestException $e) {
            // 进行错误处理
            echo $e->getMessage()."\n";
            if ($e->hasResponse()) {
                echo $e->getResponse()->getStatusCode().' '.$e->getResponse()->getReasonPhrase()."\n";
                echo $e->getResponse()->getBody();
            }
            return;
        }
    }
    
    // 解密函数
    public function decrypt($data,$sessionKey){
        $this->General = General::instance();
        
        $data = json_decode($data,true);
        $ciphertext = $data['resource']['ciphertext'];
        $nonce = $data['resource']['nonce'];
        if(isset($data['resource']) && !empty($data['resource'])){
            $associated_data = $data['resource']['associated_data'];
            $aesutil = new AesUtil($sessionKey);
            $res = json_decode($aesutil->decryptToString($associated_data, $nonce, $ciphertext),true);
            file_put_contents('log2.txt', json_encode($res)."\n", FILE_APPEND);
            if($res && ($res['action_type']=="CREATE_COMPLAINT" || $res['action_type']=="CONTINUE_COMPLAINT") || $res['action_type']=="USER_RESPONSE" || $res['action_type']=="RESPONSE_BY_PLATFORM" ){
                $postData['out_trade_no'] = $out_trade_no = $res['out_trade_no'];
                $post_url = 'https://testlkc.lkcsz.com/treasure/index/getMchidByOrderNo?orderNo='.$out_trade_no;
                $mch_id = curlPost($post_url,$postData);
                file_put_contents('log3.txt', json_encode($mch_id)."\n", FILE_APPEND);
                $payer_phone = $res['payer_phone'];
                $complaint_id = $res['complaint_id'];

                
                $payer_phone = $res['payer_phone'];
                $postData['out_trade_no'] = $out_trade_no = $res['out_trade_no'];
                $workorder_orders = db('workorder_orders')->where('out_trade_no',$out_trade_no)->find();
                
                $userInfo = db('user')->where('username',$payer_phone)->find();
                $complaint_time = $res['complaint_time'];
                $amount = $res['amount'];
                $payer_phone = $res['payer_phone'];
                $complaint_detail = $res['complaint_detail']?$res['complaint_detail']:' ';
                $complaint_state = $res['complaint_state'];
                $transaction_id = $res['transaction_id'];
                $complaint_handle_state = $res['complaint_handle_state'];
                $action_type = $res['action_type'];

                if(!$userInfo){
                    $userid = $this->auth->register($payer_phone, '123456', '', $payer_phone);
                    $userInfo = db('user')->where('username',$payer_phone)->find();
                }

                $history = $this->getHistorys($complaint_id);
                $history_arr = json_decode($history,true);
                if($userInfo){
                    if($history_arr['total_count']>0){
                        foreach($history_arr['data'] as $key=>$history_item){
                            $log_id = $history_item['log_id'];
                            $isset_log_id = db('workorder_records')->where('log_id',$log_id)->find();
                            if($isset_log_id) continue;
                            if($history_item['operate_type']=='USER_CREATE_COMPLAINT' ){
                                $row = [
                                    'complainted_mchid'=>isset($mch_id->data->mchid)?$mch_id->data->mchid:'',
                                    'out_trade_no'=>$out_trade_no,
                                    'amount' => $amount,
                                    'complaint_state' => $complaint_state,
                                    'transaction_id' => $transaction_id,
                                    'complaint_handle_state' => $complaint_handle_state,
                                    'action_type' => $action_type,
                                    'complaint_id' => $complaint_id,
                
                                    'title'=>$out_trade_no,
                                    'describe'=>$history_item['operate_details']?$history_item['operate_details']:' ',
                                    'mobile'=>$payer_phone,
                                    'createtime'=>$complaint_time,
                                    'updatetime'=>$complaint_time,
                                ];
                                if($sessionKey == 'aa6661b2b1700feba54f10259b3b82cc'){
                                    $category = 4;
                                }
                                $row['category_id'] = $category;
                                if(!$workorder_orders){
                                    $res_createReply = $this->General->createOrder($row, $userInfo['id']);
                                    $workorder_orders = db('workorder_orders')->where('out_trade_no',$out_trade_no)->find();
                                    print_r([1,$res_createReply]);
                                }

                                // 检查是否有图片
                                if(isset( $history_item['complaint_media_list']['media_url'])){
                                    $history_media_url = $history_item['complaint_media_list']['media_url'];
                                    foreach($history_media_url as $history_media_url_item){
                                        
                                        $media_res = $this->getComplainImage($history_media_url_item);
                                        $media_res_arr = json_decode($media_res,true);
                                        if(isset($media_res_arr['media_id'])){
                                            if($userInfo){                                    
                                                if(isset($workorder_orders['out_trade_no']) && !empty($workorder_orders['out_trade_no'])){ // 同个订单，是回复
                                                    $row_replay = [
                                                        'reply_describe'=>$media_res_arr['full_path'],
                                                        'reply_confidential'=>'',
                                                        'reply_type'=>1,
                                                        'media_id'=>$media_res_arr['media_id'],
                                                        'log_id'=>$log_id,
                                                        
                                                    ];
                                                    $order = Orders::get($workorder_orders['id']);
                                                    $user = User::get($userInfo['id']);
                                                    $res_createReply = $this->General->createReply($order, $user, NULL, $row_replay);
                                                    $this->assignconfig('editor_name', $this->getEditorName());
                                                }
                                            }
                                        }
                                    }
                                }

                                continue;
                            }
                            
                            $updateDate['status'] = 2;
                            db('workorder_orders')->where('out_trade_no',$out_trade_no)->update($updateDate);

                            if($history_item['operate_type']=='USER_RESPONSE' || $history_item['operate_type'] == 'USER_CONTINUE_COMPLAINT'){
                                if(isset( $history_item['complaint_media_list']['media_url'])){
                                    $history_media_url = $history_item['complaint_media_list']['media_url'];
                                    foreach($history_media_url as $history_media_url_item){
                                        
                                        $media_res = $this->getComplainImage($history_media_url_item);
                                        $media_res_arr = json_decode($media_res,true);
                                        if(isset($media_res_arr['media_id'])){
                                            if($userInfo){                                    
                                                if(isset($workorder_orders['out_trade_no']) && !empty($workorder_orders['out_trade_no'])){ // 同个订单，是回复
                                                    $row_replay = [
                                                        'reply_describe'=>$media_res_arr['full_path'],
                                                        'reply_confidential'=>'',
                                                        'reply_type'=>1,
                                                        'media_id'=>$media_res_arr['media_id'],
                                                        'log_id'=>$log_id,
                                                        
                                                    ];
                                                    $order = Orders::get($workorder_orders['id']);
                                                    $user = User::get($userInfo['id']);
                                                    $res_createReply = $this->General->createReply($order, $user, NULL, $row_replay);
                                                    $this->assignconfig('editor_name', $this->getEditorName());
                                                }
                                            }
                                        }
                                    }
                                }else{
                                    if(isset($workorder_orders['out_trade_no']) && !empty($workorder_orders['out_trade_no'])){ // 同个订单，是回复
                                        $row_replay = [
                                            'reply_describe'=>$history_item['operate_details'],
                                            'reply_confidential'=>'',
                                            'reply_type'=>0,
                                            'log_id'=>$history_item['log_id'],
                                            
                                        ];
                                        $order = Orders::get($workorder_orders['id']);
                                        $user = User::get($userInfo['id']);
                                        $res_createReply = $this->General->createReply($order, $user, NULL, $row_replay);
                                        $this->assignconfig('editor_name', $this->getEditorName());
                                    }
                                }
                            }
                           
                        }
                       
                    }
                }
               
exit;

               
                
    
            }
        }
        
    }

    protected function getEditorName()
    {
        $editor     = ['nkeditor', 'umeditor', 'markdown', 'tinymce', 'simditor', 'ueditor', 'summernote'];
        $editorList = get_addon_list();
        foreach ($editor as $item) {
            if (array_key_exists($item, $editorList) && $editorList[$item]['state'] == 1) {
                return $item;
            }
        }
        return 'none';
    }

    // 获取证书
    public function getCertificateLKC(){
        try {
            $certificate_differ = db('certificate_differ')->select();
            foreach($certificate_differ as $item){
                $url = "https://api.mch.weixin.qq.com/v3/certificates";
                $sign                        = $this -> getSign_fen($url, 'GET', '', $item['MCHID'],$item['serial_number']); //获取签名
                $sign                        = ' WECHATPAY2-SHA256-RSA2048 '.$sign; //认证类型  拼接 签名
                $return                      = http_get_curl($url, $sign);// http_post_json($url, $dsg, $sign); //请求接口
                if(isset($return['code']) && $return ['code']=='SIGN_ERROR') continue;
                
                $getData = new AesUtil($item['apivthree']);
                if(!isset($return['data'])){
                    file_put_contents('./errorcertificate.txt', json_encode([$item,$return], JSON_UNESCAPED_UNICODE).PHP_EOL,FILE_APPEND);
                    continue;
                }
                $disposeReturnData = $return['data'][0]['encrypt_certificate'];  //将变量由json类型数据转换为数组
                $associatedData = $disposeReturnData['associated_data'];  //获取associated_data数据,附加数据
                $nonceStr = $disposeReturnData['nonce'];                  //获取nonce数据,加密使用的随机串
                $ciphertext = $disposeReturnData['ciphertext'];           //获取ciphertext数据,base64编码后的数据密文

                $result = $getData -> decryptToString($associatedData,$nonceStr,$ciphertext); //调用微信官方给出的方法将解密后的数据赋值给变量
                $dir = './wechatpayCertificate/'.$item['MCHID'].'/';
                $mode = 0777;//最高权限
                if (is_dir($dir) == false) {//如果路径不存在，则创建
                    @mkdir($dir, $mode,true);
                    chmod($dir, 0777);
                }
                $ext = '.txt';//生成日记文件类型，一般常用txt类型
                file_put_contents($dir.'wechatpayCertificate.pem',$result);
                //$this->wechatpayCertificate = $result; 
            }
        } catch (RequestException $e) {
            // 进行错误处理
            echo $e->getMessage()."\n";
            if ($e->hasResponse()) {
                echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
            }
            return;
        }
    }
    

    /**
     * 作用 生成Authorization内容
     * @param $url 接口地址
     * @param $http_method  请求方式
     * @return string  响应值
     * @serial_no API证书序列号
     */
    public function getSign_fen($url, $http_method, $body='',$merchant_id = null,$serial_no = null)
    {
        $privateKey = file_get_contents('./certificate/'.$merchant_id.'/cert/apiclient_key.pem');
        
        $url_parts     = parse_url($url);
        $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
        $nonce         = $this -> createNoncestr();//随机字符串
        $timestamp     = time();//时间戳
        $message = $http_method."\n".
            $canonical_url."\n".
            $timestamp."\n".
            $nonce."\n".
            $body."\n";
        openssl_sign($message, $raw_sign, $privateKey, 'sha256WithRSAEncryption');
        $sign = base64_encode($raw_sign);
        $token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
            $merchant_id, $nonce, $timestamp, $serial_no, $sign);

        return $token;
    }

    /**
     * 作用：产生随机字符串，不长于32位
     * @param int $length
     * @return string
     */
    public function createNoncestr( $length = 32 )
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str ="";
        for ( $i = 0; $i < $length; $i++ )  {
            $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
        }
        return $str;
    }
    

    public function uploadImg($imgUrl){
        file_put_contents('./1.txt', json_encode($imgUrl).PHP_EOL,FILE_APPEND);
        // 接下来，正常使用Guzzle发起API请求， WechatPayMiddleware 会自动地处理签名和验签
        $media = new MediaUtil($imgUrl);

        // 正常使用Guzzle发起API请求
        try {
            $resp = $this->client->request('POST', 'https://api.mch.weixin.qq.com/v3/merchant-service/images/upload', [
                'body'    => $media->getStream(),
                'headers' => [
                    'Accept'       => 'application/json',
                    'content-type' => $media->getContentType(),
                ]
            ]);
            $img = json_decode($resp->getBody(), true);
            return $img['media_id'];
            $this->replyComplain($complaint_id,$complainted_mchid,$response_content);
            
            file_put_contents('./1.txt', json_encode([$img['media_id'],$resp->getReasonPhrase(),$resp->getStatusCode()]).PHP_EOL,FILE_APPEND);
            echo $resp->getStatusCode().' '.$resp->getReasonPhrase()."\n";
            echo $resp->getBody()."\n";
            echo 1;
         } catch (Exception $e) {
            echo $e->getMessage()."\n";
            echo $e->getMessage(),$e->getLine(),$e->getFile();
            echo 2;
            return;
        } 
    }
   

}

